﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Microsoft.DirectX;
using Ord;

namespace Ordonnance
{
    class Gl
    {
        /// <summary>Список доступных на сервере ботов (id-бота, имя бота)</summary>
        public static Dictionary<byte, String> BotList = new Dictionary<byte,string>();

        /// <summary>
        /// Лидирующие города игроков
        /// возвр. массив листов. В массиве 5 эл. - 5 городов 
        /// значение элемента массива - лист из номеров игроков, лидирующих в этом городе
        /// номеров может быть несколько из-за ничьи 
        /// </summary>
        public static List<int>[] LeaderMap(List<Player> pl)
        {
            List<int>[] ldr = new List<int>[5];

            if(pl.Count==0) return ldr;
            if(pl.Count==1) return ldr;

            // пробегаемся по всем городам
            for (int t = 0; t < 5; t++)
            { 
                // смотрим лидера в текущем городе (их может быть несколько в случае ничьи)
                // выставляем лидером первого игрока
                Town LeaderT = pl[0].town[t];
                // номера игроков с лидирующим городом
                List<int> n = new List<int>();
                n.Add(0);
                for (int p = 1; p < pl.Count; p++)
                { 
                    // сравниваем лидера
                    Town.LeaderStat ret = LeaderT.Leader(pl[p].town[t]);
                    if (ret == 0) n.Add(p);
                    else if(ret== Town.LeaderStat.Lose)
                    {
                        n.Clear();
                        n.Add(p);
                        LeaderT = pl[p].town[t];
                    }
                }

                // смотрим лидеров в этом городе
                ldr[t] = n;
            }

            return ldr;
        }

    }

    public class Position
        {
            public float x;
            public float y;
            public float z;
            public float angX;
            public float angY;
            public float angVis;
            public Position(float X, float Y, float Z, float AngX, float AngY, float AngleVis)
            {
                x = X;
                y = Y;
                z = Z;
                angX = AngX;
                angY = AngY;
                angVis = AngleVis;
            }
            public bool Equal(float X, float Y, float Z, float AngX, float AngY, float AngleVis)
            {
                if (x != X) return false;
                if (y != Y) return false;
                if (z != Z) return false;
                if (angX != AngX) return false;
                if (angY != AngY) return false;
                if (angVis != AngleVis) return false;
                return true;
            }

            public Vector3 pos { get { return new Vector3(x, y, z); } }
        }

    public class Game:Ord.Game
    {
        public int SelTown = -1; // выбранный игроком город для добавления карты
        public int Ipl = -1; // игрок, которым играет клиент
        public String fPathSave; // путь к файлу с сейвом
        public bool bPanaram = false; // панарамный вид
        public Position[] PosPanaram;

        #region *** GameOver **********************************************

        public bool bGameOver = false; // игра окончена. Подведение итогов
        public List<Lead> leadL = null;
        public float TimeWin = 0;

        public class Lead
        {
            public int KolVoTowns = 0;
            public List<int> idPl = new List<int>();
            public Lead(int idPl0, int KolVoTowns)
            {
                idPl.Add(idPl0);
                this.KolVoTowns = KolVoTowns;
            }
        }

        List<Lead> GetLead(List<Player> pl)
        {
            int pLen = pl.Count;
            // создаем 2 параллельных массива
            int[] lt = new int[pLen]; // количество выиграных городов для каждого игрока
            int[] lp = new int[pLen]; // номер игрока
            List<int>[] ldr = Gl.LeaderMap(pl); // массив городов с листом лидеров в каждом городе
            for (int t = 0; t < 5; t++)
                for (int i = 0; i < ldr[i].Count; i++)
                    lt[ldr[t][i]]++;
            for (int p = 0; p < pLen; p++)
                lp[p] = p;

            // сортируем массивы по убыванию лидирующих городов
            for (int i = 0; i < pLen; i++)
                for (int j = 0; j < pLen; j++)
                {
                    if (lt[i] > lt[j] & i != j)
                    {
                        int c = lt[i];
                        int c1 = lp[i];
                        lt[i] = lt[j];
                        lp[i] = lp[j];
                        lt[j] = c;
                        lp[j] = c1;
                    }
                }
            List<Lead> ret = new List<Lead>();

            // заполняем лидерство
            ret.Add(new Lead(lp[0], lt[0]));
            int ActL = 0;
            for (int p = 1; p < pLen; p++)
            {
                // если у следующего игрока столько же городов, добавляем его в то же место
                if (ret[ActL].KolVoTowns == lt[p])
                {
                    ret[ActL].idPl.Add(lp[p]);
                }
                // иначе добавляем в новое место
                else
                {
                    ret.Add(new Lead(lp[p], lt[p]));
                    ActL++;
                }

            }
            return ret;
        }

        public bool GameIsOver()
        {
            for (int p = 0; p < pl.Count; p++)
                for (int t = 0; t < 5; t++)
                    if (pl[p].town[t].card.Count < 4)
                    {
                        bGameOver = false;
                        return false;
                    }

            leadL = GetLead(pl);
            bGameOver = true;
            return true;
        }

        #endregion *** GameOver **********************************************

        public Game(String Name, String Moderator)
            :base(Name, Moderator)
        {

        }

        /*public Game(Buf)
            : base(Name, Moderator)
        {

        }*/

        public void RefillPosPanaram(float stepXPl, float AngVis)
        {
            PosPanaram = new Position[8];
            for (int i = 0; i < 8; i++)
            {
                float aX = 65;
                float aY = 0;
                float z = -25;
                if (i % 2 == 1)
                {
                    aY = 180;
                    z = 25;
                }
                float x = stepXPl * (i / 2);

                if (pl.Count > 2)
                {
                    if (i < 2) x += stepXPl / 2;
                    else if (i > pl.Count - 3) x -= stepXPl / 2;
                }
                PosPanaram[i] = new Position(x, 50, z, aX, aY, AngVis);
            }
        }

        public void CopyGamePlayData(Game gm)
        {
            SelTown = gm.SelTown; // выбранный игроком город для добавления карты
            Ipl = gm.Ipl; // игрок, которым играет клиент
            fPathSave = gm.fPathSave; // путь к файлу с сейвом
            PlayPl = gm.PlayPl; // игрок, ходящий в данный момент
            bPanaram = gm.bPanaram; // панарамный вид
            PosPanaram = gm.PosPanaram;
            pl = gm.pl; // лист игроков
        }

    }

}
